package dao

import (
	"errors"
	"fmt"
	"time"
	"user_srv/handler/models"
)

// 提现常量
const (
	MinWithdrawalAmount     = 100.0   // 最小提现金额
	MaxWithdrawalAmount     = 50000.0 // 最大提现金额
	DefaultWithdrawalStatus = 0       // 默认待审核状态
)

// 账户类型常量
const (
	AccountTypeBank   = 1 // 银行卡
	AccountTypeAlipay = 2 // 支付宝
	AccountTypeWeChat = 3 // 微信
)

// 审核状态常量
const (
	StatusPending     = 0 // 待审核
	StatusApproved    = 1 // 审核通过
	StatusRejected    = 2 // 审核拒绝
	StatusWithdrawing = 3 // 提现中
	StatusSuccess     = 4 // 提现成功
	StatusFailed      = 5 // 提现失败
)

// CreateWithdrawal 创建提现申请（包含业务逻辑）
func CreateWithdrawal(withdrawal *models.Withdrawal) (*models.Withdrawal, error) {
	// 参数验证
	if err := validateWithdrawalParams(withdrawal.Amount, withdrawal.AccountType, withdrawal.AccountNumber, withdrawal.AccountName); err != nil {
		return nil, err
	}

	// 生成提现单号
	withdrawalNo := generateWithdrawalNo(withdrawal.UserID)

	withdrawal = &models.Withdrawal{
		UserID:        withdrawal.UserID,
		WithdrawalNo:  withdrawalNo,
		Amount:        withdrawal.Amount,
		AccountType:   withdrawal.AccountType,
		AccountNumber: withdrawal.AccountNumber,
		AccountName:   withdrawal.AccountName,
		BankName:      withdrawal.BankName,
		Status:        DefaultWithdrawalStatus,
	}

	if err := withdrawal.Create(); err != nil {
		return nil, fmt.Errorf("创建提现申请失败: %w", err)
	}

	return withdrawal, nil
}

// validateWithdrawalParams 验证提现参数
func validateWithdrawalParams(amount float64, accountType int8, accountNumber, accountName string) error {
	if amount <= 0 {
		return errors.New("提现金额必须大于0")
	}
	if amount < MinWithdrawalAmount {
		return fmt.Errorf("提现金额不能少于%.2f元", MinWithdrawalAmount)
	}
	if amount > MaxWithdrawalAmount {
		return fmt.Errorf("单笔提现金额不能超过%.2f元", MaxWithdrawalAmount)
	}
	if accountType < AccountTypeBank || accountType > AccountTypeWeChat {
		return errors.New("收款账户类型无效")
	}
	if accountNumber == "" {
		return errors.New("收款账号不能为空")
	}
	if accountName == "" {
		return errors.New("收款人姓名不能为空")
	}
	return nil
}

// generateWithdrawalNo 生成提现单号
func generateWithdrawalNo(userID uint64) string {
	return fmt.Sprintf("WD%d%d", time.Now().Unix(), userID)
}

// GetWithdrawalByID 根据ID查询提现记录
func GetWithdrawalByID(id uint64) (*models.Withdrawal, error) {
	if id == 0 {
		return nil, errors.New("提现ID不能为空")
	}
	withdrawal := &models.Withdrawal{ID: id}
	err := withdrawal.GetByID()
	return withdrawal, err
}

// GetWithdrawalByNo 根据提现单号查询
func GetWithdrawalByNo(withdrawalNo string) (*models.Withdrawal, error) {
	if withdrawalNo == "" {
		return nil, errors.New("提现单号不能为空")
	}
	withdrawal := &models.Withdrawal{WithdrawalNo: withdrawalNo}
	err := withdrawal.GetByWithdrawalNo()
	return withdrawal, err
}

// GetUserWithdrawals 获取用户的提现记录列表
func GetUserWithdrawals(userID uint64, page, pageSize int) ([]*models.Withdrawal, int64, error) {
	if userID == 0 {
		return nil, 0, errors.New("用户ID不能为空")
	}
	page, pageSize = normalizePagination(page, pageSize)
	withdrawal := &models.Withdrawal{UserID: userID}
	return withdrawal.GetByUserID(page, pageSize)
}

// GetAllWithdrawals 获取所有提现记录（管理员）
func GetAllWithdrawals(page, pageSize int) ([]*models.Withdrawal, int64, error) {
	page, pageSize = normalizePagination(page, pageSize)
	withdrawal := &models.Withdrawal{}
	return withdrawal.GetAll(page, pageSize)
}

// UpdateWithdrawalStatus 更新提现状态（包含业务逻辑）
func UpdateWithdrawalStatus(id uint64, status int8, auditorID uint64, reason string) error {
	// 参数验证
	if err := validateAuditParams(status, reason); err != nil {
		return err
	}

	withdrawal := &models.Withdrawal{ID: id}
	if err := withdrawal.UpdateStatus(status, auditorID, reason); err != nil {
		return fmt.Errorf("更新提现状态失败: %w", err)
	}

	return nil
}

// validateAuditParams 验证审核参数
func validateAuditParams(status int8, reason string) error {
	if status != StatusApproved && status != StatusRejected {
		return errors.New("审核状态无效")
	}
	if status == StatusRejected && reason == "" {
		return errors.New("拒绝提现必须填写拒绝原因")
	}
	return nil
}

// normalizePagination 标准化分页参数
func normalizePagination(page, pageSize int) (int, int) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}
	if pageSize > 100 {
		pageSize = 100
	}
	return page, pageSize
}

// UpdateWithdrawal 更新提现记录
func UpdateWithdrawal(withdrawal *models.Withdrawal) error {
	return withdrawal.Update()
}

// SumWithdrawalAmount DAO层统计提现金额
// start: 开始时间，格式: 2024-01-01 或 2024-01-01 00:00:00
// end: 结束时间，格式: 2024-01-31 或 2024-01-31 23:59:59
// groupType: 分组类型 1=按日 2=按月 3=按年
func SumWithdrawalAmount(start, end string, groupType int) ([]string, []float64, error) {
	// 参数验证
	if groupType < 1 || groupType > 3 {
		return nil, nil, fmt.Errorf("分组类型无效，仅支持1(按日)/2(按月)/3(按年)")
	}
	return models.SumAmountGroup(start, end, groupType)
}
